<template>
	<view class="speech">
		<view class="upload" v-show="uploadBefore">
			<view class="file-box" @click="afterRead">

				<view class="upload-content">
					<image class="upload-icon" src="../../static/image/upload.png"></image>
					<view class="upload-text">选择文件</view>
				</view>
				<!-- </u-upload> -->
			</view>
			<view class="upload-tip">注:仅支持wav、mp3格式，大小不能超过5GB</view>
		</view>

		<view class="upload-after" v-if="uploadAfter">
			<view class="file-list">
				<view class="file-icon">
					<!-- <u-icon name="photo" size="40"></u-icon> -->
					<image style="height: 80rpx; width: 80rpx;" :src="localIconSrc('yuyin.png')"></image>
				</view>
				<view class="file-text">
					<view class="file-name">{{ fileName }}</view>
					<view class="file-size">大小：{{ fileSize }}</view>
				</view>
			</view>
			<view class="file-btn" v-if="!progress">
				<button class="choose btn" @click="afterRead">重选文件</button>
				<button class="sub-btn btn" @click="execute">{{ title == '语音识别' ? '转文本' : '开始处理'}}</button>
			</view>
			<view class="progress" v-if="progress">
				<progress-circle ref="progress" class="circle-progress" :progress="percent" :percent="percents"
					:text="text"></progress-circle>
			</view>
		</view>

		<view class="success-box" v-show="uploadSuccess">
			<view v-if="title == '语音识别'">
				<uni-easyinput type="textarea" autoHeight v-model="content" placeholder=""></uni-easyinput>
				<view class="file-btn">
					<button class="new-btn btn" @click="copyOrder">复制文本</button>
					<button class="sub-btn btn">保存文档</button>
				</view>
			</view>

			<view v-if="title == '语音降噪'">
				<view class="file-list">
					<view class="file-icon">
						<image style="height: 80rpx; width: 80rpx;" :src="localIconSrc('yuyin.png')"></image>
					</view>
					<view class="file-text">
						<view class="file-name">{{ fileName }}</view>
						<view class="file-size">大小:{{ fileSize }}</view>
					</view>
				</view>
				<button class="save-btn" @click="saveFile">保存音频</button>
			</view>
		</view>
	</view>
	</view>
</template>

<script>
	import {
		getUploadUrl,
		getToolList,
		getFileUrl,
		taskExec
	} from '@/api/task.js'
	import progressCircle from '@/components/progress.vue'
	// import VueServerSentEvents from 'vue-server-sent-events';
	import {
		Base64
	} from '@/static/base64.js'
	export default {
		components: {
			progressCircle
		},
		data() {
			return {
				fileList: [],
				uploadBefore: true, // 上传文件前
				uploadAfter: false, // 上传成功后显示文件信息
				progress: false, // 转文字上的进度条
				uploadSuccess: false, // 转文字成功后
				content: '', // 转化的文字内容
				productCode: 'audio-chinese-recognition',
				title: '',
				fileName: '',
				fileSize: '',
				taskid: '',
				percent: 0.1, // 进度条
				percents: 10,
				denoiseUrl: '',
				text: '任务执行中，请勿离开页面...',
				titles: true,
				time2: null,
				flag: false,
				timeSet:null
			}
		},
		onLoad(param) {
			this.title = param.title;
			uni.setNavigationBarTitle({
				title: param.title
			})
		},
		onShow() {
			this.getToolsCode()
		},
		onUnload() {
			clearTimeout(this.time2)
			clearInterval(this.timeSet)
		},
		methods: {
			// 效率工具列表
			async getToolsCode() {
				const tools = await getToolList();
				const {
					audio
				} = tools.data
				console.log('tool', tools);
				audio.forEach(ele => {
					if (ele.title.indexOf(this.title) !== -1) {
						console.log(ele.product_code)
						this.productCode = ele.product_code
					}
				})
				console.log('code', this.productCode)

			},
			async getUrl() {
				const uploadUrl = await getUploadUrl();
				console.log('upload', uploadUrl);
			},

			// 上传文件后的钩子
			afterRead(file, lists, name) {
				if (!uni.getStorageSync('apiticket')) {
					uni.showModal({
						title: "提示",
						content: "请先登录",
						success(res) {
							if (res.confirm) {
								setTimeout(() => {
									uni.navigateTo({
										url: "/pages/login/index",
									})
								}, 1000);
							}
						},
					});
					return
				}

				wx.chooseMessageFile({
					success: (res) => {
						console.log('res', res);

						// tempFilePath可以作为img标签的src属性显示图片
						// const tempFilePaths = res.tempFiles
						console.log('res', res);
						const filePath = res.tempFiles[0].path;
						const fileName = res.tempFiles[0].name;
						const fileSize = res.tempFiles[0].size;
						
						const allowedTypes = ['wav', 'mp3']
						const isAllowed = allowedTypes.includes(fileName);
						const fileExtension = fileName.match(/\.(\w+)$/)[1];
						console.log('isAllowed', fileSize)
						if (fileExtension != 'wav' && fileExtension != 'mp3') {
							uni.showToast({
								title:'只能上传MP3或WAV格式的文件！',
								icon:'none',
								duration: 3000
							});
							return false
						}
						if (fileSize > 5 * 1024 * 1024 * 1024) {
							uni.showToast({
								title:'上传文件大小不能超过5GB',
								icon:'error',
								duration: 3000
							});
							return false
						}
						
						this.fileName = fileName;
						this.fileSize = this.formatBytes(fileSize)
						
						let pathData = {};
						console.log('pathRes', fileName)
						const fileSystemManager = wx.getFileSystemManager();

						// 读取文件
						fileSystemManager.readFile({
							filePath: filePath,
							success: (readRes) => {
								// 在这里处理文件流，readRes.data就是文件的二进制数据
								console.log('文件流：', readRes);
								this.uploadFile(fileName, this.productCode, readRes.data)
							},
							fail: (err) => {
								console.error('读取文件失败：', err);
							}
						});
					}
				})

			},
			async uploadFile(name, code, pathData) {
				uni.showLoading({
					title: '正在上传...'
				})
				let data = {
					filename: name,
					product_code: code
				}
				// 获取文件上传的地址
				const uploadRes = await getUploadUrl(data);
				const {
					url,
					token,
					taskid
				} = uploadRes;
				this.taskid = taskid;

				// monio直传
				uni.request({
					url: url, //后端返回的签名地址
					data: pathData, //上传的文件字节流
					method: 'PUT',
					header: {
						'Content-Type': 'application/octet-stream', //此处注意
						'Content-Disposition': 'inline'
					},
					success: (minio) => {
						console.log("直传返回", minio);
						// 上传到minio成功后储存到服务器
						let tokenStr = {
							token: token
						}
						getFileUrl(tokenStr).then(urlRes => {
							console.log('urlRes', urlRes);
							this.uploadAfter = true; // 显示文件信息
							this.uploadBefore = false; // 关闭上传框
							uni.hideLoading()
						})
					}
				});
			},

			// 转文本
			execute() {
				this.progress = true;
				let param = {
					taskid: this.taskid
				}
				taskExec(param).then(res => {
					console.log('res', res);
					const { domain, taskid, domain_socket } = res;
					const webUrl = `wss://${domain_socket}/api/v1?clienid=${taskid}`
					this.testAI(webUrl)
				}).catch(err => {
					this.progress = false;
				})
			},
			// 接入see
			testAI(seeUrl) {

				const webs = uni.connectSocket({
					url: seeUrl,
					header: {
						'content-type': 'application/json'
					},
					success: (res) => {
						console.log(res)
					},
					fail: (err) => {
						console.log(err)
					}
				})
				webs.onOpen((e) => {
					console.log('open', e)
					// 进度条
					this.timeSet = setInterval(() => {
						this.percent += 0.01;
						this.percents += 1;
						this.$refs.progress.drawCircle(this.percent)
						if (this.percent > 0.9) {
							clearInterval(this.timeSet);
							this.percent = 0.95;
							this.percents = 95
						}
					}, 1000);
					
				})
				webs.onError((e) => {
					console.log('err', e)
				})
				webs.onMessage((e) => {
					console.log('message', JSON.parse(e.data));
					const successData = JSON.parse(e.data);
					const successCode = successData.msg_content;
					if (successCode.data && successCode.errcode == '200') {
						console.log('successCode', successCode, this.title);
						this.percent = 10
						this.percents = 100
						this.uploadAfter = false; // 显示文件信息
						this.uploadBefore = false;
						this.uploadSuccess = true; // 成功后显示
						this.content = successCode.data[0].text // 语音识别
						this.denoiseUrl = successCode.data // 降噪
						this.flag = true
						clearTimeout(this.time2)
						console.log('successCode', this.uploadSuccess, this.uploadBefore);
					}
				})
				webs.onClose((e) => {
					console.log('close', e)
					if(!this.flag) {
						clearInterval(this.timeSet);
						this.percent = 0;
						this.percents = 0;
						this.uploadBefore = true;
						this.uploadAfter = false
						this.progress = false
						clearTimeout(this.time2)
					}
				});

				// 300秒关闭连接
				this.time2 = setTimeout(function() {
					uni.closeSocket();
					uni.showToast({
						title: '超时，请重试',
						icon: 'none'
					})
				}, 300000); // 300000
			},

			// 保存音频
			async saveFile() {
				uni.downloadFile({
					url: this.denoiseUrl,
					success:(successRes) => {
						console.log('success', successRes.tempFilePath)
						uni.saveVideoToPhotosAlbum({
							filePath: this.denoiseUrl,
							success: (saveRes) => {
								console.log('音频保存成功', saveRes);
							},
						})
					},
				});
				// try {
				// 	// const url = this.denoiseUrl // mp3 文件的 url
				// 	// const downloadResult = await uni.downloadFile({ url }) // 下载文件
				// 	// console.log('downloadResult', downloadResult)
				// 	// const tempFilePath = downloadResult.tempFilePath // 下载后的临时文件路径
				// 	// console.log('tempFilePath', tempFilePath)

				// 	// const saveResult = await uni.saveFile({ tempFilePath }) // 保存文件到本地
				// 	// const savedFilePath = saveResult.savedFilePath // 文件保存后的路径
				// 	// console.log('文件保存成功，路径为', savedFilePath)
				// } catch (error) {
				// 	console.error(error)
				// }
			},
			
			// 复制文本
			copyOrder() {
				uni.setClipboardData({
					data: this.content,
					success: () => {
						uni.showToast({
							title: '复制成功',
							icon: 'success',
							duration: 2000
						});
					},
					fail: () => {
						uni.showToast({
							title: '复制失败',
							icon: 'none',
							duration: 2000
						});
					}
				});
			},

			// 转化文件大小
			formatBytes(bytes, decimals = 2) {  
				if (bytes === 0) return '0 Bytes';  
				const k = 1024;  
				const dm = decimals < 0 ? 0 : decimals;  
				const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];  
				const i = Math.floor(Math.log(bytes) / Math.log(k));  
				return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];  
			},
		}
	}
</script>

<style lang="scss" scoped>
	.speech {
		background: #fff;
		height: 100vh;
		// padding: 200rpx 54rpx;
	}

	.upload {
		padding: 200rpx 54rpx;
	}

	.success-box {
		padding: 40rpx 54rpx;

		.file-list {
			background: #d9d9d9;
			border-radius: 20rpx;
			display: flex;
			align-items: center;
			padding: 32rpx;

			.file-text {
				margin-left: 20rpx;
				width: 80%;

				.file-name {
					font-size: #{$text-size};
					color: #{$one-title-color};
					word-wrap: break-word;
				}

				.file-size {
					font-size: #{$auxiliary-size};
					color: #{$sub-color};
				}
			}
		}

		.save-btn {
			background: #{$main-color};
			color: #fff;
			font-size: #{$one-title-size};
			border-radius: 40rpx;
			margin-top: 40rpx;
		}
	}

	.file-box {
		height: 344rpx;
		background: #f5f5f5;
		border-radius: 16rpx;
	}

	.upload-box {
		height: 100%;
		width: 100%;
		position: relative;
	}

	.upload-content {
		width: 640rpx;
		height: 344rpx;
		position: relative;
	}

	.upload-text {
		color: #{$main-color};
		font-size: #{$one-title-size};
		margin-top: 40rpx;
		position: absolute;
		top: 50%;
		left: 50%;
		transform: translate(-50%);
	}

	.upload-icon {
		// border: 2px solid #333;
		border-radius: 50%;
		width: 96rpx;
		height: 96rpx;
		line-height: 60rpx;
		position: absolute;
		top: 30%;
		left: 50%;
		transform: translate(-50%);
	}

	.upload-tip {
		font-size: #{$auxiliary-size};
		color: #{$sub-color};
		margin-top: 60rpx;
	}

	.upload-after {
		padding: 40rpx 54rpx;

		.file-list {
			background: #d9d9d9;
			border-radius: 20rpx;
			display: flex;
			align-items: center;
			padding: 32rpx;

			.file-text {
				margin-left: 20rpx;
				width: 80%;

				.file-name {
					font-size: #{$text-size};
					color: #{$one-title-color};
					word-wrap: break-word;
				}

				.file-size {
					font-size: #{$auxiliary-size};
					color: #{$sub-color};
				}
			}
		}
	}

	.file-btn {
		display: flex;
		margin-top: 120rpx;

		.btn {
			font-size: #{$one-title-size};
			width: 300rpx;
			border-radius: 40rpx;
			border: 1px solid #{$main-color};
		}

		.new-btn {
			color: #{$main-color};
		}

		.sub-btn {
			background: #{$main-color};
			color: #fff;
		}
	}

	.progress {
		position: relative;
		margin-top: 120rpx;

		.circle-progress {
			position: absolute;
			left: 50%;
			transform: translate(-50%);
		}
	}

	.progress-text {
		text-align: center;
		margin-top: 340rpx;
	}

	.choose {
		background: transparent;
		border-radius: 60rpx;
		width: 300rpx;
		color: #ff6005;
		border: 1px solid #ff6005;
	}
</style>